package com.applet.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.applet.annotation.SystemServerLog;
import com.applet.entity.request.*;
import com.applet.entity.response.LoginOutResponse;
import com.applet.entity.response.RegisterResponse;
import com.applet.entity.response.UserResponse;
import com.applet.entity.response.VerificationCodeSmsResponse;
import com.applet.enums.ResultEnums;
import com.applet.model.LoginLog;
import com.applet.model.RegisterLog;
import com.applet.model.ReplacePhoneLog;
import com.applet.model.UserInfo;
import com.applet.requestService.SmsRequestService;
import com.applet.service.UserService;
import com.applet.utils.AppletResult;
import com.applet.utils.ResultUtil;
import com.applet.utils.baidu.BaiduYingYanUtils;
import com.applet.utils.common.GsonTools;
import com.applet.utils.common.Md5Util;
import com.applet.utils.common.UuidUtil;
import com.applet.utils.common.VeriCodeUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
public class UserServiceImpl extends BaseServiceImpl implements UserService{

    private static final String SmsKey = "VerificationCodeSmsKey_";

    @Autowired
    private SmsRequestService smsRequestService;

    private static final Logger LOGGER= LoggerFactory.getLogger(UserServiceImpl.class);

    @SystemServerLog(funcionExplain = "打开App传数据")
    @Override
    public AppletResult open(OpenRequest openRequest){
        return ResultUtil.success();
    }

    @SystemServerLog(funcionExplain = "发送短信验证码")
    @Override
    public AppletResult sendVerificationCode(VerificationCodeRequest verificationCodeRequest){
        VerificationCodeSmsRequest verificationCodeSmsRequest = new VerificationCodeSmsRequest();
        verificationCodeSmsRequest.setPhone(verificationCodeRequest.getPhone());
        verificationCodeSmsRequest.setCode(VeriCodeUtils.getMessageCode(4));
        AppletResult response = smsRequestService.getLockInfoRequest(verificationCodeSmsRequest);
        if(response.getCode() == 200){
            return ResultUtil.success(ResultEnums.SMS_RETURN_SUCCESS,null);
        }else {
            if(response.getCode() == 1002){
                return ResultUtil.error(ResultEnums.ERROR_SMS_REPEAT);
            }
            return ResultUtil.error(ResultEnums.ERROR_SMS_SEND);
        }
    }

    @SystemServerLog(funcionExplain = "用户注册")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppletResult register(RegisterRequest registerRequest){
        UserInfo userInfo = userInfoMapper.selectByPhone(registerRequest.getPhone());
        if(userInfo == null){
            if(redisUtil.getValueObj(SmsKey + registerRequest.getPhone()) == null){
                return ResultUtil.error(ResultEnums.ERROR_USER_NULL_GET_CODE);
            }
            String code = redisUtil.getValueObj(SmsKey + registerRequest.getPhone()).toString();
            if(!StringUtils.isBlank(code)){
                if(registerRequest.getCode().equals(code)){
                    String uuid = UuidUtil.getUuid();
                    UserInfo newUserInfo = new UserInfo();
                    newUserInfo.setId(uuid);
                    newUserInfo.setAccountStatus(0);
                    newUserInfo.setAppVersion(registerRequest.getAppVersion());
                    newUserInfo.setCreditScore(100);
                    newUserInfo.setSystemVersion(registerRequest.getOsInformation());
                    newUserInfo.setOpenDate(new Date());
                    newUserInfo.setPhone(registerRequest.getPhone());
                    newUserInfo.setNickname("会员用户");
                    try {
                        if(!StringUtils.isBlank(registerRequest.getLatitude()) &&
                                !StringUtils.isBlank(registerRequest.getLongitude())){
                            String city = BaiduYingYanUtils.geocoder(registerRequest.getLatitude(),registerRequest.getLongitude());
                            newUserInfo.setRegisterCity(city);
                        }
                    }catch (Exception e){
                        LOGGER.error(e.getMessage());
                    }

                    if(!StringUtils.isBlank(registerRequest.getDeviceId())){
                        if(registerRequest.getPlat().equals("ios")){
                            newUserInfo.setIdfa(registerRequest.getDeviceId());
                        }else if(registerRequest.getPlat().equals("android")){
                            newUserInfo.setImei(registerRequest.getDeviceId());
                        }
                    }
                    if(!StringUtils.isBlank(registerRequest.getMac())){
                        newUserInfo.setMac(registerRequest.getMac());
                    }
                    newUserInfo.setCreateDate(new Date());
                    newUserInfo.setPassword(Md5Util.MD5(registerRequest.getPassword()));
                    userInfoMapper.insertSelective(newUserInfo);

                    RegisterLog registerLog = new RegisterLog();
                    registerLog.setUserId(uuid);
                    registerLog.setCode(registerRequest.getCode());
                    registerLog.setLat(registerRequest.getLatitude());
                    registerLog.setLng(registerRequest.getLongitude());
                    registerLog.setDeviceid(registerRequest.getDeviceId());
                    registerLog.setPassword(Md5Util.MD5(registerRequest.getPassword()));
                    registerLog.setMac(registerRequest.getMac());
                    registerLog.setPhone(registerRequest.getPhone());
                    registerLogMapper.insertSelective(registerLog);

                    redisUtil.deteleObjKey(SmsKey + registerRequest.getPhone());
                    return ResultUtil.success(ResultEnums.REGISTER_RETURN_SUCCESS,null);
                }else {
                    return ResultUtil.error(ResultEnums.ERROR_USER_REGISTER_CODE);
                }
            }else{
                return ResultUtil.error(ResultEnums.ERROR_USER_REGISTER);
            }
        }else {
            return ResultUtil.error(ResultEnums.ERROR_USER_REGISTER_REPEAT);
        }
    }

    @SystemServerLog(funcionExplain = "用户登陆")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppletResult<UserResponse> login(LoginRequest loginRequest){
        UserInfo userInfo = userInfoMapper.selectByPhone(loginRequest.getPhone());
        if(userInfo != null){
            if(userInfo.getPassword().equals(Md5Util.MD5(loginRequest.getPassword()))){
                if(!StringUtils.isBlank(loginRequest.getAppVersion())){
                    userInfo.setAppVersion(loginRequest.getAppVersion());
                }
                userInfo.setLoginState(1);
                userInfo.setLoginTime(new Date());
                userInfoMapper.updateByPrimaryKeySelective(userInfo);

                LoginLog loginLog = new LoginLog();
                loginLog.setUserId(userInfo.getId());
                loginLog.setLoginState(1);
                loginLog.setLat(loginRequest.getLatitude());
                loginLog.setLng(loginRequest.getLongitude());
                loginLog.setCreateDate(new Date());
                loginLog.setAppVersion(loginRequest.getAppVersion());
                loginLogMapper.insertSelective(loginLog);

                String userJson = GsonTools.createGsonString(userInfo);
                UserResponse userResponse = GsonTools.changeGsonToBean(userJson,UserResponse.class);
                return ResultUtil.success(ResultEnums.RETURN_SUCCESS,userResponse);
            }else{
                return ResultUtil.error(ResultEnums.ERROR_USER_PASSWORD);
            }
        }else {
            return ResultUtil.error(ResultEnums.ERROR_USER_NULL_REGISTER);
        }
    }

    @SystemServerLog(funcionExplain = "用户退出登陆")
    @Override
    @Transactional(rollbackFor = Exception.class)
    public AppletResult loginOut(LoginOutRequest loginOutRequest){
        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(loginOutRequest.getUserId());
        if(userInfo != null){
            userInfo.setLoginState(0);
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
            LoginLog loginLog = new LoginLog();
            loginLog.setUserId(userInfo.getId());
            loginLog.setLoginState(0);
            loginLog.setLat(loginOutRequest.getLatitude());
            loginLog.setLng(loginOutRequest.getLongitude());
            loginLog.setCreateDate(new Date());
            loginLog.setAppVersion(loginOutRequest.getAppVersion());
            loginLogMapper.insertSelective(loginLog);

            return ResultUtil.success(ResultEnums.LOGINOUT_RETURN_SUCCESS,null);
        }else{
            return ResultUtil.error(ResultEnums.NULL_USER_INFO);
        }
    }

    @SystemServerLog(funcionExplain = "修改用户昵称")
    @Override
    public AppletResult modifyNickName(ModifyNickNameRequest modifyNickNameRequest){
        UserInfo userInfo = userInfoMapper.selectByPrimaryKey(modifyNickNameRequest.getUserId());
        if(userInfo != null){
            userInfo.setNickname(modifyNickNameRequest.getNickName());
            userInfoMapper.updateByPrimaryKeySelective(userInfo);
            String userJson = GsonTools.createGsonString(userInfo);
            UserResponse userResponse = GsonTools.changeGsonToBean(userJson,UserResponse.class);
            return ResultUtil.success(ResultEnums.RETURN_SUCCESS,userResponse);
        }else {
            return ResultUtil.error(ResultEnums.ERROR_USER_MODIFY_NICKNAME);
        }
    }


    @SystemServerLog(funcionExplain = "修改手机号")
    @Override
    public AppletResult modifyPhone(ModifyPhoneRequest modifyPhoneRequest){
        if(redisUtil.getValueObj(SmsKey + modifyPhoneRequest.getPhone()) == null){
            return ResultUtil.error(ResultEnums.ERROR_USER_NULL_GET_CODE);
        }
        String code = redisUtil.getValueObj(SmsKey + modifyPhoneRequest.getPhone()).toString();
        if(!StringUtils.isBlank(code)){
            if(modifyPhoneRequest.getCode().equalsIgnoreCase(code)){
                UserInfo userInfo = userInfoMapper.selectByPrimaryKey(modifyPhoneRequest.getUserId());
                if(userInfo == null){
                    return ResultUtil.error(ResultEnums.NULL_USER_INFO);
                }else {
                    if(modifyPhoneRequest.getType() == 0){
                        return ResultUtil.success(ResultEnums.RETURN_SUCCESS,null);
                    }else if(modifyPhoneRequest.getType() == 1){
                        UserInfo info = userInfoMapper.selectByPhone(modifyPhoneRequest.getPhone());
                        if(info != null){
                            return ResultUtil.error(ResultEnums.ERROR_USER_MODIFY_PHONE);
                        }else {
                            ReplacePhoneLog replacePhoneLog = new ReplacePhoneLog();
                            replacePhoneLog.setId(UuidUtil.getUuid());
                            replacePhoneLog.setOldPhone(userInfo.getPhone());
                            replacePhoneLog.setNewPhone(modifyPhoneRequest.getPhone());
                            replacePhoneLog.setCreateDate(new Date());
                            replacePhoneLog.setUserId(userInfo.getId());
                            userInfo.setPhone(modifyPhoneRequest.getPhone());
                            userInfoMapper.updateByPrimaryKeySelective(userInfo);

                            String userJson = GsonTools.createGsonString(userInfo);
                            UserResponse userResponse = GsonTools.changeGsonToBean(userJson,UserResponse.class);
                           return ResultUtil.success(ResultEnums.RETURN_SUCCESS,userResponse);
                        }
                    }else {
                        return ResultUtil.error(ResultEnums.SERVER_ERROR);
                    }
                }
            }else {
                return ResultUtil.error(ResultEnums.ERROR_USER_REGISTER_CODE);
            }
        }else {
            return ResultUtil.error(ResultEnums.ERROR_USER_NULL_GET_CODE);
        }
    }

}
